﻿using System.Drawing;
using System.Windows.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Client.Service;
using System.Collections;
using GenericModels;


namespace Client
{
    public partial class UserCtlSeats : UserControl
    {
        public Booking booking { get; set; }
        public event UserControlClickHandler InnerButtonClickReturn;
        public event UserControlClickHandler InnerButtonClickConfirm;
        public delegate void UserControlClickHandler(object sender, EventArgs e);

        private IShow showService;
        private ISeat seatService;
        private IBooking bookingService;
        private IPerson personService;
        private LocaterStates locState;
        private List<Seat> UserSelectedSeats;
        private int adultValue;
        private int childValue;
        private int seniorValue;
        private int totalTicketsSelected;
        private int totalseat;
        private int itotalseat;

        private int row;
        private int col;
        private List<Seat> AlgorithmSeats;
        private int middleIndex;
        private int rowIndex;
        private int columnIndex;
        private int middleSeat;
        private string lastTime;
        private int movesLeft;
        private int movesRight;


        private Dictionary<int, Button> roomOutline;
        private Show show { get; set; }
        private Customer customer { get; set; }
        public Employee employee { get; set; }

        private const int AVAILABLE_SEAT = 0;
        private const int RESERVED_SEAT = 1;
        private const int LOCKED_SEAT = 2;

        private IDictionary<Button, Seat> seats;
        private IList<Seat> listOfSeats;

        public UserCtlSeats(Booking booking, Customer cus, Employee employee)
        {
            //PickBestSeat();
            InitializeComponent();
            this.booking = booking;
            this.customer = cus;
            this.employee = employee;

            bookingService = new BookingClient("WSHttpBinding_IBooking");
            showService = new ShowClient("WSHttpBinding_IShow");
            seatService = new SeatClient("WSHttpBinding_ISeat");
            personService = new PersonClient("WSHttpBinding_IPerson");

            seats = new Dictionary<Button, Seat>();
            roomOutline = new Dictionary<int, Button>();
            show = booking.PbList[CurrentPartId()].TheShow;

            listOfSeats = seatService.GetAllSeatsOnShow(show);            //create a list of the seats assigned to this show.
            UserSelectedSeats = new List<Seat>();                         //stores seats selected directly by the user
            
            InitAlternativeAlgorithmVars();
            CreateRoom();
            ComboInformation();
            PopulateCombobox();
            LoadEmployeePic();
            LoadBookingInfo();
        }

        #region Inits
        /// <summary>
        /// Instantiates the variables required for the smooth operating of the alternative algorithm.
        /// </summary>
        private void InitAlternativeAlgorithmVars()
        {

            row = Convert.ToInt32(show.Room.Row);              //Antal rækker i salen
            col = Convert.ToInt32(show.Room.Col);               //Antal kolonner i salen

            movesLeft = 0;
            movesRight = 0;
            lastTime = "middle";
            AlgorithmSeats = new List<Seat>();
            middleIndex = (row * col) / 2;                      //Det midterste index
            rowIndex = row / 2;                                 //Midterste række
            columnIndex = col / 2;                              //Midterste kolonne    
            middleSeat = listOfSeats[middleIndex].SeatId;

            //MessageBox.Show("middleIndex: " + middleIndex.ToString() + " - row index: " + rowIndex.ToString() +
            //                " - col index: " + columnIndex.ToString() + " - middleSeat: " + middleSeat.ToString() +
            //                " - Rows: " + row.ToString() + " - Cols: " + col.ToString() + "NoOfSeats: " + listOfSeats.Count.ToString());
        }

        /// <summary>
        /// Display show information on the gui
        /// </summary>
        public void ComboInformation()
        {

            lblShow.Text = show.Type.Title;
            lblDate.Text = show.Date.Date.ToLongDateString();
            lblShowTime.Text = show.Date.TimeOfDay.ToString();
            lblRoomNr.Text = show.Room.RoomNumber.ToString();
            
            lblPrice1.Text = "DKR:  " + show.Prices[1].TicketPrice.ToString();
            lblPrice2.Text = "DKR:  " + show.Prices[0].TicketPrice.ToString();
            lblPrice3.Text = "DKR:  " + show.Prices[2].TicketPrice.ToString();
        }

        /// <summary>
        /// Creates the showroom, using the helpermethods: CreateButtons(), and CreateRoomLayout()
        /// </summary>
        private void CreateRoom()
        {
            Point[] p = new Point[listOfSeats.Count()];
            Button[] button = new Button[listOfSeats.Count()];

            for (int i = 0; i < listOfSeats.Count; i++)
            {
                CreateButtons(button, i, p);

            }
            CreateRoomLayout(button, p);

            //MessageBox.Show(" total : " + total.ToString() + " itotal :" + itotal.ToString() + " meditotal :" + mediItotal.ToString() + " bestseat :" + bestSeat.ToString());
        }

        /// <summary>
        /// Creates the buttons, each of which represents a seat.
        /// </summary>
        /// <param name="button"></param>
        /// <param name="i"></param>
        /// <param name="p"></param>
        private void CreateButtons(Button[] button, int i, Point[] p)
        {
            button[i] = new Button();                   //create new button

            if (listOfSeats[i].Status == "0")                  //if the seat is not taken
                button[i].BackColor = Color.Green;
            if (listOfSeats[i].Status == "1")                  //if the seat is reserved
                button[i].BackColor = Color.Yellow;
            if (listOfSeats[i].Status == "2")
                button[i].BackColor = Color.Red;        //if the seat has been confirmed

            button[i].Height = 30;      //Størrelsen på knappen højde
            button[i].Width = 30;       //Størrelsen på knappen brede
            //button[i].Text = ((i + 1).ToString());    //Sætter sæde nummer
            button[i].Text = listOfSeats[i].SeatId.ToString(); //sets the button text to the seatId
            button[i].Click += new EventHandler(button_Click);  //add clickevent
            p[i] = new Point();

            seats.Add(button[i], listOfSeats[i]);                       //adds the button and the available seats to a list, thus linking them. SKAL UD!!
            roomOutline.Add(listOfSeats[i].SeatId, button[i]);          //adds the 

            totalseat += listOfSeats[i].SeatId;
            itotalseat += i;
        }

        /// <summary>
        /// Creates the panel in which the seats are stored, and displayed
        /// 
        /// </summary>
        /// <param name="button"></param>
        /// <param name="p"></param>
        private void CreateRoomLayout(Button[] button, Point[] p)
        {

            FlowLayoutPanel pan = new FlowLayoutPanel();

            pan.Width = Convert.ToInt32(booking.PbList[CurrentPartId()].TheShow.Room.Col) * 40;     //Sets the width of the panel based on the size of the room
            pan.Height = Convert.ToInt32(booking.PbList[CurrentPartId()].TheShow.Room.Row) * 40;     //Sets the height of the panel based on the size of the room
            pan.Controls.AddRange(button);                     //adds the button[] to the flowpanel
            
            pnlSeat.Controls.Add(pan);                         //adds the flowpanel to the seatPanel

         
        }
        #endregion

        #region tickets

        /// <summary>
        /// Fill the ticket comboboxes.
        /// Also, sets the default number of selected tickets at 1 regular adult.
        /// NOTE: The Alternative Algorithm does not work with more than one type of tickets
        /// </summary>
        public void PopulateCombobox()
        {
            string[] ad = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            cbAdult.Items.AddRange(ad);
            string[] ch = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            cbChild.Items.AddRange(ch);
            string[] se = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            cbSenior.Items.AddRange(se);

            //set default ticket value at 1 regular adult.
            totalTicketsSelected = 1;
            cbAdult.SelectedIndex = 1;
            cbChild.SelectedIndex = 0;
            cbSenior.SelectedIndex = 0;

        }

        #region ticketValues
        /// <summary>
        /// Assigns a number of tickets for the type Adult, based on the combobox index
        /// </summary>
        public void Adult()
        {
            switch (cbAdult.SelectedIndex)
            {
                case 0:
                    adultValue = 0;
                    break;
                case 1:
                    adultValue = 1;
                    break;
                case 2:
                    adultValue = 2;
                    break;
                case 3:
                    adultValue = 3;
                    break;
                case 4:
                    adultValue = 4;
                    break;
                case 5:
                    adultValue = 5;
                    break;
                case 6:
                    adultValue = 6;
                    break;
                case 7:
                    adultValue = 7;
                    break;
                case 8:
                    adultValue = 8;
                    break;
                case 9:
                    adultValue = 9;
                    break;
            }
        }

        public void Child()
        {

            switch (cbChild.SelectedIndex)
            {
                case 0:
                    childValue = 0;
                    break;
                case 1:
                    childValue = 1;
                    break;
                case 2:
                    childValue = 2;
                    break;
                case 3:
                    childValue = 3;
                    break;
                case 4:
                    childValue = 4;
                    break;
                case 5:
                    childValue = 5;
                    break;
                case 6:
                    childValue = 6;
                    break;
                case 7:
                    childValue = 7;
                    break;
                case 8:
                    childValue = 8;
                    break;
                case 9:
                    childValue = 9;
                    break;
            }

        }

        public void Senior()
        {
            switch (cbSenior.SelectedIndex)
            {
                case 0:
                    seniorValue = 0;
                    break;
                case 1:
                    seniorValue = 1;
                    break;
                case 2:
                    seniorValue = 2;
                    break;
                case 3:
                    seniorValue = 3;
                    break;
                case 4:
                    seniorValue = 4;
                    break;
                case 5:
                    seniorValue = 5;
                    break;
                case 6:
                    seniorValue = 6;
                    break;
                case 7:
                    seniorValue = 7;
                    break;
                case 8:
                    seniorValue = 8;
                    break;
                case 9:
                    seniorValue = 9;
                    break;
            }
        }
        #endregion

        /// <summary>
        /// Triggered if a change is made to the "adult" combobox
        /// Updates the amount of tickets for this type
        /// Calculates the total number of tickets
        /// Calculates the total price of the booking
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbAdult_SelectedIndexChanged(object sender, EventArgs e)
        {
            Adult();
            CalculateNoOfTickets();
            CalculateBookingPrice();

        }

        /// <summary>
        /// Triggered if a change is made to the "child" combobox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbChild_SelectedIndexChanged(object sender, EventArgs e)
        {
            Child();
            CalculateNoOfTickets();
            CalculateBookingPrice();

        }

        /// <summary>
        /// Triggered if a change is made to the "senior" combobox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbSenior_SelectedIndexChanged(object sender, EventArgs e)
        {
            Senior();
            CalculateNoOfTickets();
            CalculateBookingPrice();

        }

        /// <summary>
        /// Calculates the total number of tickets selected.
        /// Maximum amount on a single booking is 9
        /// Calls the alternative algorithm on the total number of selected tickets
        /// </summary>
        public void CalculateNoOfTickets()
        {

            totalTicketsSelected = adultValue + childValue + seniorValue;

            if (totalTicketsSelected <= 9 && totalTicketsSelected > 0)
            {
               
                AlternativeAlgorithm(totalTicketsSelected);
            }
            else
            {
                MessageBox.Show("Ugyldigt antal billetter valgt");
                totalTicketsSelected = 1;
                lblSum.Text = totalTicketsSelected.ToString();
                cbAdult.SelectedIndex = 1;
                cbChild.SelectedIndex = 0;
                cbSenior.SelectedIndex = 0;

            }

        }

        /// <summary>
        /// Calculates the total sum of the booked seats
        /// Assigns the value to the GUI, and the booking
        /// </summary>
        private void CalculateBookingPrice()
        {
            float price = 0.0f;

            float adultPrice = show.Prices[1].TicketPrice;
            float childPrice = show.Prices[0].TicketPrice;
            float seniorPrice = show.Prices[2].TicketPrice;
            price = (adultPrice * adultValue) + (childPrice * childValue) + (seniorPrice * seniorValue);
            booking.TotalPrice = price;

            lblSum.Text = price.ToString();
        }

        #endregion

        #region Click Events and event helper methods
        /// <summary>
        /// Each button represents a seat.
        /// Clicking, selects, or deselects a seat.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void button_Click(object sender, EventArgs e)
        {
            ClearAlgorithm();                       //clears all information collected by Alternative Algorithm

            Button b = (Button)sender;
            Seat s = seats[b];


            s = seatService.GetSeat(s.SeatId);      
            //MessageBox.Show(b.BackColor.ToString());

            //checks the current color of the seat, and changes accordingly
            switch (b.BackColor.ToString())
            {
                case "Color [Green]":       
                    b.BackColor = Color.Yellow;                   //switch seat color to yellow
                    //booking.PbList[CurrentPartId()].Seats.Add(s); //Add seat to the reserved list.
                    UserSelectedSeats.Add(s);
                    break;
                case "Color [Yellow]":
                    b.BackColor = Color.Green;
                    //Removes the seat from the "desired" list
                    //Incidently, I have no idea why this works. Probably science....
                    Seat thisSeat = UserSelectedSeats.Single(x => x.SeatId == s.SeatId);
                    //Seat thisSeat = booking.PbList[CurrentPartId()].Seats.Single(x => x.SeatId == s.SeatId);
                    //booking.PbList[CurrentPartId()].Seats.Remove(thisSeat);
                    UserSelectedSeats.Remove(thisSeat);
                    break;
                case "Color [Red]":
                    MessageBox.Show("Sædet er booket");     //notifies the user that the seat is booked.
                    break;
            }
        }
   
        /// <summary>
        /// Performs the necessary actions so as to move the booking forward
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfirm_Click(object sender, EventArgs e)
        {
            //tilføj booking til customer her
            if (this.InnerButtonClickConfirm != null)
            {
                LockConfirmed();                    //Lock the selected seats in the database
                AddSeatsToPartBooking();            //Add the seats to the partbooking
                AddEmployeeToBooking();             //Add the employee to the booking
                InsertBookingInDatabase();          //Inserts the booking into the database
                InsertPartBookingInDatabase();      //Inserts the partbooking into the database

                if(personService.AddBookingToCustomer(customer, booking)) //use personService to add booking to customer 
                {
                    this.InnerButtonClickConfirm(sender, e);
                }
                else
                {
                    MessageBox.Show("booking was´nt inserted in customers bookings");
                }
 
                //MessageBox.Show("seats on booking " + booking.PbList[CurrentPartId()].Seats.Count.ToString());
                
            }
        }

        private void AddEmployeeToBooking()
        {
            booking.EmpId = employee.EmployeeId;
        }

        /// <summary>
        /// adds the booking to the customers list of bookings
        /// </summary>
        private void AddBookingToCustomer()
        {
            customer.AddBooking(booking);
        }      

        /// <summary>
        /// Locks the confirmed seats in the database (status = 2)
        /// </summary>
        private void LockConfirmed()
        {
            seatService.LockSeat(AppropriateSeatList(), LOCKED_SEAT);
        }
 
        /// <summary>
        /// Add the selected seats from their current list, to the list maintained by the partbooking
        /// </summary>
        private void AddSeatsToPartBooking()
        {
            foreach (Seat s in AppropriateSeatList())
            {
                booking.PbList[CurrentPartId()].Seats.Add(s);
            }
        }

        /// <summary>
        /// Helper method, which calls the service to insert the booking in the database, also updates the booking property
        /// </summary>
        private void InsertBookingInDatabase()
        {
            booking.BookingId = bookingService.InsertBooking(booking).BookingId;    //Ensures that the booking property is updated with the newly aquired bookingId
        }

        //Helper method, which calls the service to insert the partbooking in the database, also updates the partbooking on the booking
        private void InsertPartBookingInDatabase()
        {
            booking.PbList[CurrentPartId()].BookingId = booking.BookingId;                                                  //Ensure that the partbooking is updated with the booking id, failure to do so
            booking.PbList[CurrentPartId()].Id = bookingService.InsertPartBooking(booking.PbList[CurrentPartId()]).Id;      //will result in an exception due to foreign key constriction on partbooking.
            //MessageBox.Show(booking.PbList.Count.ToString());
        }

        /// <summary>
        /// Removes the current, unsaved, partbooking, and sends the user back to the movieselection screen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBack_Click(object sender, EventArgs e)
        {
            if (this.InnerButtonClickReturn != null)
            {
                booking.PbList.RemoveAt(CurrentPartId());   //delete current, unsaved, partbooking

                this.InnerButtonClickReturn(sender, e);
            }
        }

        #endregion

        #region Alternative Algorithm
        /// <summary>
        /// Uses a state machine pattern to locate the best available seats.
        /// "Best" being defined as: Closest to the middle of the theatre
        /// </summary>
        /// <param name="noOfSeats"></param>
        private void AlternativeAlgorithm(int noOfSeats)
        {

            ClearUserSelected();                        //Clears all information about seats selected by the user
            bool found = false;                         //Bliver brugt til at komme ud af while loopet

            locState = LocaterStates.Init;              //Sets the initial state to Init            

            while (!found)                              //the loop will run until the "found" requirements are met
            {
                switch (locState)                       //calls whichever method the state dictates, Init() is always the first to be called
                {
                    case LocaterStates.Init:
                        Init();
                        break;
                    case LocaterStates.Middle:
                        Middle();
                        break;
                    case LocaterStates.LeftMove:
                        LeftMove();
                        break;
                    case LocaterStates.RightMove:
                        RightMove();
                        break;
                    case LocaterStates.Found:
                        found = Found(noOfSeats);       //checks if the loop is ready to be terminated
                        break;
                }
            }
        }

        /// <summary>
        /// Used to ensure that the default requirements of the state machine is met
        /// sets the state to "middle"
        /// </summary>
        private void Init()
        {
            //MessageBox.Show("Init state");
            ClearUserSelected();
            ClearAlgorithm();
            locState = LocaterStates.Middle;
        }

        /// <summary>
        /// Checks to see if the seat in the middle of the room is available
        /// Only run once, but serves as default whenever the algoritm is called.
        /// </summary>
        private void Middle()
        {
            //MessageBox.Show("middle state");
            Seat s = seatService.GetSeat(middleSeat);                   //retrieve the seat to check on.
            if (s.Status == "0")                                        //check if seat is available
            {
                AddSeat(s, "middle");                                   //See method for comments
            }
            else
            {
                movesLeft++;
                movesRight++;
            }

            locState = LocaterStates.Found;                             //In either case, set state to "Found"
        }

        /// <summary>
        /// Check if the current seat left of the middle is available
        /// By default, left side is checked before right. 
        /// </summary>
        private void LeftMove()
        {
            //MessageBox.Show("Left state");
            Seat s = seatService.GetSeat(middleSeat + movesLeft);       //seat is found by adding the number of times left has been tried, to the middleseat id
            if (s.Status == "0")
            {
                AddSeat(s, "left");
            }
            else
            {
                lastTime = "left"; 
                movesLeft++;
            }

            locState = LocaterStates.Found;
        }

        /// <summary>
        /// Check if the current seat right of the middle is available
        /// </summary>
        private void RightMove()
        {
            //MessageBox.Show("Right state");
            Seat s = seatService.GetSeat(middleSeat - movesRight);      //seat is found by subtracting the number of times right has been tried, from the middleseat id
            if (s.Status == "0")
            {
                AddSeat(s, "right");
            }
            else
            {
                lastTime = "right";
                movesRight++;
            }
            locState = LocaterStates.Found;
        }

        /// <summary>
        /// Checks if the required number of seats has been located, by comparing 
        /// foundSeats to the amount of seats specified in the method parameter.
        /// if true, sets the boolean value to true, which signifies the endstate
        /// if false, determine which direction was attempted last, and sets the state accordingly
        /// 
        /// </summary>
        /// <param name="noOfSeats"></param>
        /// <returns>bool</returns>
        private bool Found(int noOfSeats)
        {
            //MessageBox.Show("found state");
            bool done = false;
            if (AlgorithmSeats.Count.Equals(noOfSeats))         //check if the required number of seats has been located
            {
                done = true;
            }
            else
            {
                switch (lastTime)                           //switch based on what direction was attempted last
                {
                    case "middle":
                        locState = LocaterStates.LeftMove;      //if the last attempt was middle, the specified default direction to attempt, is left
                        break;
                    case "left":
                        locState = LocaterStates.RightMove;     //if the last attempt was left, then go right
                        break;
                    case "right":
                        locState = LocaterStates.LeftMove;      //if the last attempt was right, then go left
                        break;
                }
            }
            return done;                                    //boolean return value

        }

        /// <summary>
        /// helper method, called by the algorithm if an available seat has been located
        /// adds the seat, and sets the algorithm variables accordingly
        /// </summary>
        /// <param name="s"></param>
        /// <param name="direction"></param>
        private void AddSeat(Seat s, string direction)
        {
            switch (direction)
            {
                case "middle":
                    roomOutline[s.SeatId].BackColor = Color.BlueViolet;     //if available, color the seat
                    AlgorithmSeats.Add(s);                                      //and add it to the foundSeats list
                    lastTime = direction;
                    movesLeft++;                                            //add one to the "left" pointer
                    movesRight++;                                           //add one to the "right" pointer
                    break;
                case "left":
                    roomOutline[s.SeatId].BackColor = Color.BlueViolet;
                    AlgorithmSeats.Add(s);
                    lastTime = direction;                                      //marks left as the most recent direction attempted
                    movesLeft++;
                    break;
                case "right":
                    roomOutline[s.SeatId].BackColor = Color.BlueViolet;
                    AlgorithmSeats.Add(s);
                    lastTime = direction;
                    movesRight++;
                    break;
            }

        }
        #endregion

        #region Helper Methods

        /// <summary>
        /// Returns the partbooking id for this partbooking
        /// </summary>
        /// <returns></returns>
        private int CurrentPartId()
        {
            return booking.PbList.Count - 1;     //the current show is always the last on the partbooking list
        }


        /// <summary>
        /// Resets algorithm values, and all data collected by the algorithm
        /// Called in the Init() and when the user manually selects a seat
        /// </summary>
        private void ClearAlgorithm()
        {
            movesLeft = 0;                                            //reset moves
            movesRight = 0;
            lastTime = "middle";                                      //default value for lastTime, as the algoritm always starts in the middle, and this 
                                                                      //would be skewed by the usage of Init() if a fourth "state" did not exist for lastTime
            foreach (Seat s in AlgorithmSeats)                        //foreach seat which may have been found by the algorithm
            {
               roomOutline[s.SeatId].BackColor = Color.Green;        //set the color of those seats to green
            }

            AlgorithmSeats.Clear();                                  //finally, clear the list. These seats are not to be used in any capacity.
        }


        /// <summary>
        /// Resets the seats selected by the user, and empties the seat list
        /// Called when the Algorithm is called.
        /// </summary>
        private void ClearUserSelected()
        {
            foreach (Seat s in UserSelectedSeats)
            {
                roomOutline[s.SeatId].BackColor = Color.Green;
            }
            UserSelectedSeats.Clear();
        }

        /// <summary>
        /// Helper method which determines which seat list contains the selected seats.
        /// If both are empty, returns the UserSelectedSeats list, because why not..
        /// </summary>
        /// <returns>A List<Seat></returns>
        private List<Seat> AppropriateSeatList()
        {
            if (AlgorithmSeats.Count.Equals(0))
            {
                return UserSelectedSeats;
            }
            else
            {
                return AlgorithmSeats;
            }
        }

        /// <summary>
        /// Loads an employee and sets his/her information on the screen
        /// </summary>
        private void LoadEmployeePic()
        {
            pictureBox1.ImageLocation = "http://www.mynetimages.com/4f992650cb.jpg";
            lblEmpName.Text = employee.FName;
            lblEmpTitle.Text = employee.Title;
        }

        /// <summary>
        /// Retrieves a customer, and prints his/her booking information on the screen
        /// </summary>
        private void LoadBookingInfo()
        {
            lblCusName.Text = customer.FName;
            if (booking == null)
            {
                lblBookId.Text = "0"; //Empty booking object
                lblPartId.Text = "0"; //Empty Partbooking object
            }
            else
            {
                lblBookId.Text = booking.BookingId.ToString();
                lblPartId.Text = booking.PbList[booking.PbList.Count - 1].Id.ToString();
            }
        }
        #endregion
    }



    
    /// <summary>
    /// The entries in this enum, are used as states
    /// which can be selected by the Alternative Algorithm state machine.
    /// </summary>
    public enum LocaterStates
    {
        Init,
        Middle,
        LeftMove,
        RightMove,
        Found
    }
}
